#pragma once

#include "ISistema.h"
#include "Prueba.h"

class CasoDePrueba : public Prueba
{
public:
	CasoDePrueba(Puntero<ISistema> (*inicializar)(nat VEOLCIDAD_OMNIBUS, nat VELOCIDAD_AVION, nat COSTO_OMNIBUS, nat COSTO_AVION, nat CAPACIDAD_OMNIBUS, nat CAPACIDAD_AVION, nat MAX_CIUDADES, nat MAX_EXCURSIONES, nat MAX_CLIENTES));
	virtual ~CasoDePrueba();

protected:
	virtual void CorrerPruebaConcreta();
	virtual Cadena GetNombre() const;

private:
	Puntero<ISistema> (*inicializar)(nat VEOLCIDAD_OMNIBUS, nat VELOCIDAD_AVION, nat COSTO_OMNIBUS, nat COSTO_AVION, nat CAPACIDAD_OMNIBUS, nat CAPACIDAD_AVION, nat MAX_CIUDADES, nat MAX_EXCURSIONES, nat MAX_CLIENTES);
	Puntero<ISistema> InicializarSistema(nat VEOLCIDAD_OMNIBUS = 60, nat VELOCIDAD_AVION = 240, nat COSTO_OMNIBUS = 10, nat COSTO_AVION = 50, nat CAPACIDAD_OMNIBUS = 40, nat CAPACIDAD_AVION = 200, nat MAX_CIUDADES = 30, nat MAX_EXCURSIONES = 20, nat MAX_CLIENTES = 60);
	Puntero<ISistema> InicializarInterfaz(bool silenciar = false);

	bool ignorarOK;
	void Verificar(TipoRetorno obtenido, TipoRetorno esperado, Cadena comentario);
	template <class T>
	void Verificar(const T& obtenido, const T& esperado, Cadena comentario);
	template <class T>
	void VerificarConjuntos(Puntero<Iterador<T>> obtenidos, Puntero<Iterador<T>> esperados, Cadena comentarioEncontrado, Cadena comentarioFalta, Cadena comentarioSobra);
	template <class T>
	void VerificarSecuencias(Puntero<Iterador<T>> obtenidos, Puntero<Iterador<T>> esperados, Cadena comentarioEncontrado, Cadena comentarioFalta, Cadena comentarioSobra);
	void VerificarConsExcursion(Tupla<TipoRetorno, Puntero<Iterador<Tupla<pCiudad, nat>>>, nat> obtenido, Tupla<TipoRetorno, Puntero<Iterador<Tupla<pCiudad, nat>>>, nat> esperado);
	void VerificarConsCliente(Tupla<TipoRetorno, pCliente, Puntero<Iterador<pExcursion>>> obtenido, Tupla<TipoRetorno, pCliente, Puntero<Iterador<pExcursion>>> esperado);
	void VerificarConsCiudad(Tupla<TipoRetorno, pCiudad, Puntero<Iterador<pExcursion>>> obtenido, Tupla<TipoRetorno, pCiudad, Puntero<Iterador<pExcursion>>> esperado);
	void VerificarMejorCliente(Tupla<TipoRetorno, pCliente> obtenido, Tupla<TipoRetorno, pCliente> esperado);
	void VerificarListCiudades(Tupla<TipoRetorno, Puntero<Iterador<pCiudad>>> obtenido, Tupla<TipoRetorno, Puntero<Iterador<pCiudad>>> esperado);
	void VerificarListClientes(Tupla<TipoRetorno, Puntero<Iterador<pCliente>>> obtenido, Tupla<TipoRetorno, Puntero<Iterador<pCliente>>> esperado);
	void VerificarListExcursiones(Tupla<TipoRetorno, Puntero<Iterador<pExcursion>>> obtenido, Tupla<TipoRetorno, Puntero<Iterador<pExcursion>>> esperado);
	bool SonIguales(const pCiudad& obtenido, const pCiudad& esperado) const;
	Cadena ObtenerTexto(const pCiudad& c) const;
	bool SonIguales(const pExcursion& obtenido, const pExcursion& esperado) const;
	Cadena ObtenerTexto(const pExcursion& e) const;
	bool SonIguales(const pCliente& obtenido, const pCliente& esperado) const;
	Cadena ObtenerTexto(const pCliente& c) const;
	bool SonIguales(const Tupla<pCiudad, nat>& obtenido, const Tupla<pCiudad, nat>& esperado) const;
	Cadena ObtenerTexto(const Tupla<pCiudad, nat>& t) const;

	void PruebaOK1();
	void PruebaOK2();
	void PruebaOK3();
	void PruebaOK4();
	void PruebaOK5();
	void PruebaOK6();
	void PruebaOK7();
	void PruebaOK8();
	void PruebaOK9();
	void PruebaOK10();
	void PruebaOK11();
	void PruebaOK12();

	void PruebaERROR1();
	void PruebaERROR2();
	void PruebaERROR3();
	void PruebaERROR4();
	void PruebaERROR5();
	void PruebaERROR6();
	void PruebaERROR7();
	void PruebaERROR8();
	void PruebaERROR9();
	void PruebaERROR10();
	void PruebaERROR11();
	void PruebaERROR12();
};